/*
 *  vehicle_robber.cpp
 *  Created by Aditya Herlambang
 *
 */

#include "robber.h"
#include "cop.h"
#include "map.h"
#include <math.h>
#include <iostream>

using namespace std;

Robber::Robber()
:escapeMode(true), myRadius(10)
{ 
	myPosition = new Position(40,50);
	hideoutPosition = new Position(25,30);
}

Robber::Robber(vector<Cop*> vcops, Position* s, Position* f, Map* _map)
:escapeMode(true)
{ 
	srand ( time(NULL) );
	cops = vcops;
	myRadius = 10;
	myPosition = s;
	hideoutPosition = f;
	map = _map;
}

Robber::~Robber()
{
 delete myPosition;
 delete hideoutPosition;
}

Robber::Robber(const Robber& other)
{
	try
    {
		*(this->myPosition) = *(other.myPosition);
		*(this->hideoutPosition) = *(other.hideoutPosition);
		  this->myRadius = other.myRadius;
    	this->escapeMode = other.escapeMode;
	}
    catch(...) // Catch all, clean up and resthrow
    {
        throw;
    }
}

Robber& Robber::operator=(const Robber& other)
{	
	if( &other != this ){
		*(this->myPosition) = *(other.myPosition);
		*(this->hideoutPosition) = *(other.hideoutPosition);
		this->myRadius = other.myRadius;
    		this->escapeMode = other.escapeMode;
	}
	
 return *this;
}

//a method that will return a position where the robber should escape if the cop is within his sight radius
Position* Robber::getEscapeRoute()
{
 int random = rand() % (Map::numberOfCols/2)*10 + 1;
 Position *res = new Position();
 Direction temp = directionHelper();

 while(!(map->nodes[(res->posY)/10][(res->posX)/10])->checkConnected()){
 	if (temp == North){
		while ((myPosition->posY) + random > Map::numberOfRows * 10 )
			random = rand() % (Map::numberOfRows/2)*10 + 1;
		res->posX = myPosition->posX;
			res->posY = myPosition->posY + random;
	
 	}else if (temp == South){
		while ((myPosition->posY) - random > 0)
			random = rand() % (Map::numberOfRows/2)*10 + 1;
		res->posX = myPosition->posX;
		res->posY = myPosition->posY - random;
 	}else if (temp == West){
		while ((myPosition->posX) - random > 0)
			random = rand() % (Map::numberOfCols/2)*10 + 1;
		res->posX = myPosition->posX-random;
		res->posY = myPosition->posY;
 	}else{
		while ((myPosition->posX) + random > Map::numberOfCols * 10)
			random = rand() % (Map::numberOfCols/2)*10 + 1;
		res->posX = myPosition->posX+ random;
		res->posY = myPosition->posY;
 	}
  }	
  return res;
}

Direction Robber::directionHelper()
{
 //0 - North
 //1 - South
 //2 - East
 //3 - West

 Direction result = West;
 vector<int> temp (4,0);

 for (int i = 0; i < cops.size(); i++){
	if (cops[i]->myDirection == North)
		temp[0] = 1;
	else if (cops[i]->myDirection == South)
		temp[1] = 1;
	else if (cops[i]->myDirection == West)
		temp[2] = 1;
	else
		temp[3] = 1;
 }

 if (temp[0] == 1 && temp[1] == 0)
	result = North;
 else if (temp[1] == 1 && temp[0] == 0)
	result = South;
 else if (temp[2] == 1 && temp[3] == 0)
	result = East;
 else
	result = West; 

 return result;
}

bool Robber::checkCopWithinRadius()
{
	bool result = false;
	for (int i = 0; i < cops.size(); i++){
		if (withinRadius(myPosition, cops[i]->myPosition, myRadius)){
			result = true;
			break;
    		}
	}
	return result;
}

void Robber::takeTurn()
{
	Position* go = getEscapeRoute();

	if (checkCopWithinRadius())
		driveTo(go);
	else
		driveTo(hideoutPosition);
	
}